package com.bx.imserver.netty;


import com.alibaba.fastjson2.JSONObject;
import com.bx.imserver.constant.LoginUser;
import com.bx.imserver.redis.RedisCache;
import com.bx.imserver.util.SecurityUtils;
import com.bx.imserver.util.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@ChannelHandler.Sharable
public class WebSocketAuthHandler extends ChannelInboundHandlerAdapter {


    // 令牌秘钥
    private String secret;

    private RedisCache redisCache;

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public RedisCache getRedisCache() {
        return redisCache;
    }

    public void setRedisCache(RedisCache redisCache) {
        this.redisCache = redisCache;
    }

    public static final AttributeKey<Boolean> AUTHORIZED = AttributeKey.newInstance("AUTHORIZED");

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        int i=0;
        if (msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;

            // 这里进行认证逻辑，比如检查请求头中的token
            boolean authenticated = authenticate(request);

            if (authenticated) {
                // 如果认证成功，将请求向下传递至下一个Handler
                ctx.channel().attr(AUTHORIZED).set(true);
                ctx.fireChannelRead(msg);
            } else {
                // 如果认证失败，关闭连接
                log.info("认证失败，连接将被关闭");
                ctx.close();
            }
        } else {
            // 如果不是HttpRequest类型，直接向下传递给下一个Handler处理
            ctx.fireChannelRead(msg);
        }
    }

    private boolean authenticate(FullHttpRequest request) {
        // 这里填写您的认证逻辑，从request中提取认证信息，如token，并进行验证
        // 如验证成功，返回true，否则返回false
        String Token = request.headers().get("Authorization");
        LoginUser loginUser =getLoginUserByToken(Token);
        if (com.bx.imserver.util.StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())){
            return true; // 示例代码，默认返回true
        }
        return false;
    }

    public LoginUser getLoginUserByToken(String token)
    {
        // 获取请求携带的令牌
        if (StringUtils.isNotEmpty(token))
        {
            try
            {
                Claims claims = parseToken(token);
                // 解析对应的权限以及用户信息
                String uuid = (String) claims.get("login_user_key");
                String userKey = getTokenKey(uuid);
                JSONObject user= redisCache.getCacheObject(userKey);
                user.remove("@type");
                LoginUser rs = user.to(LoginUser.class);
                return rs;
            }
            catch (Exception e)
            {
                System.out.println("e = " + e);
            }
        }
        return null;
    }

    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }
    private String getTokenKey(String uuid)
    {
        return "login_tokens:" + uuid;
    }
}
